﻿using UnityEngine;
using System.Collections;

// 控制摄像头，测试代码
public class OCharacterCamera : MonoBehaviour {
    public Transform _camera_transform;
    public Transform _dummy_transform;
    public Transform _target_transform;
    public enum MotionType
    {
        DummyBase,
        TargetBase,
    }
    public MotionType _motion_type = MotionType.TargetBase;
    MotionType _motion_last_type = MotionType.DummyBase;
    Quaternion _dummy_base_qot = Quaternion.identity;
    Vector3 _dummy_base_pos = Vector3.zero;
    
	// Use this for initialization
	void Start () {
        //_camera_transform = GameObject.Find("Main Camera").transform;
        _camera_transform = transform;// 挂在控制的像机上

        _dummy_transform = GameObject.Find("DummyCamera").transform.Find("Main Camera");
	}

	// Fllow character
	void LateUpdate () {
        OInput.singleton.Update();// 应该在别的什么地方搞的

        if (_dummy_transform == null)
        {
            return;// 这种设计dummy是基础
        }

        if(_motion_last_type != _motion_type)
        {
            _motion_last_type = _motion_type;
            if(_motion_type == MotionType.TargetBase)
            {
                _dummy_base_dis = (_dummy_transform.position - _dummy_transform.parent.position).magnitude;
                _dummy_base_v_angle = Quaternion.LookRotation(-_dummy_transform.right, _dummy_transform.up).eulerAngles.x;
                _v_angle = _v_angle - _dummy_base_v_angle;
            }
            else
            {
                if(_target_transform != null)
                {
                    _dummy_base_qot = _target_transform.rotation;
                    _dummy_base_pos = _target_transform.position;
                }
                else
                {
                    _dummy_base_qot = Quaternion.identity;
                    _dummy_base_pos = Vector3.zero;
                }
            }
        }


        if (_motion_type == MotionType.DummyBase || _target_transform == null)
        {
            // dummy控制
            var dummy_pos = _dummy_transform.position;
            var dummy_qot = Quaternion.LookRotation(-_dummy_transform.right, _dummy_transform.up);
            _camera_transform.rotation = _dummy_base_qot * dummy_qot;
            _camera_transform.position = _dummy_base_qot * dummy_pos + _dummy_base_pos;
        }
        else
        {
            // 目标导向
            GetTargetCenter();

            FollowLookAt();// H rotate
            ManualAction();// HV rotate, change dis
            TurnCameraAndLookAtTarget();
            CollisonCheck();// check environment
        }
	}

    // 像机看向的目标
    Vector3 _target_center = Vector3.down;
    void GetTargetCenter()
    {
        var pos = _target_transform.position;
        pos.y += 1.8f;// 胶囊体高度2

        if(_target_center == Vector3.down)
        {
            _target_center = pos;
        }
        else
        {
            var dir = _target_center - pos;
            var sqrtmg = dir.sqrMagnitude;
            var t = Mathf.Max(5, sqrtmg * 4);
            _target_center = Vector3.Lerp(_target_center, pos, Time.deltaTime * t);
        }
    }

    // 像机位置属性：角度，距离
    float _dis = 10;
    float _h_angle = 0;
    [SerializeField]
    float _v_angle = -45;
    [SerializeField]
    float _v_angle_min = -45;
    [SerializeField]
    float _v_angle_max = 80;
    void HRotate(float h_angle)
    {
        _h_angle += h_angle;
    }
    void VRotate(float v_angle)
    {
        _v_angle += v_angle;
    }
    float _dummy_base_dis = 0;
    float _dummy_base_v_angle = 0;
    // 根据外部操控和dummy motion设置像机位置，最后看下目标中心
    void TurnCameraAndLookAtTarget()
    {
        var dummy_pos = (_dummy_transform.position - _dummy_transform.parent.position);
        float dis = (_dis + dummy_pos.magnitude - _dummy_base_dis);// dummy控制的相对距离
        dummy_pos = dummy_pos.normalized * Mathf.Max(0.1f, dis);
        _v_angle = Mathf.Clamp(_v_angle + _dummy_base_v_angle, _v_angle_min, _v_angle_max);
        _v_angle -= _dummy_base_v_angle;
        dummy_pos = Quaternion.Euler(_v_angle, _h_angle, 0) * dummy_pos + _target_center;
        _camera_transform.position += (dummy_pos - _camera_transform.position)*Mathf.Min(1,Time.deltaTime*5);
        _camera_transform.LookAt(_target_center);

        
    }

    // 手动控制，相对移动
    float _manual_x_speed = 0;
    float _manual_y_speed = 0;
    [SerializeField]
    float _rotate_speed = 1;
    void ManualAction()
    {
        // 修改距离
        _dis += OInput.singleton._mouse_scroll;
        _dis = Mathf.Max(_dis, 1);

        // 转动角度
        var manual_target_x = OInput.singleton._mouse_x * _rotate_speed;
        var manual_target_y = - OInput.singleton._mouse_y * _rotate_speed;

        _manual_x_speed += (manual_target_x - _manual_x_speed) * Mathf.Min(1, Time.deltaTime * 5);
        _manual_y_speed += (manual_target_y - _manual_y_speed) * Mathf.Min(1, Time.deltaTime * 5);

        HRotate(_manual_x_speed);
        VRotate(_manual_y_speed);
    }

    // 随着目标移动，往目标目光方向，转动摄像头
    [SerializeField]
    float _follow_h_speed_basic = 1;
    float _follow_h_speed = 0;
    //[SerializeField]
    //float _follow_v_speed_basic = 1;
    //float _follow_v_speed = 0;// 垂直方向转动很怪呢。
    void FollowLookAt()
    {

        if(OInput.singleton._move_ad != 0 || OInput.singleton._move_ws != 0)
        {
            Vector3 target_look_at = _target_transform.forward;
            Vector3 camera_look_at = _camera_transform.forward;

            var rot = Quaternion.FromToRotation(camera_look_at, target_look_at).eulerAngles;

            float h_angle = rot.y;
            float h_sin = Mathf.Sin(Mathf.Deg2Rad * h_angle);
            float follow_h_speed_target = _follow_h_speed_basic * h_sin;
            _follow_h_speed += (follow_h_speed_target - _follow_h_speed) * Mathf.Min(1, Time.deltaTime * 5);
            HRotate(_follow_h_speed);

            //float v_angle = rot.x;
            //float v_sin = Mathf.Sin(Mathf.Deg2Rad * v_angle);
            //float follow_v_speed_target = _follow_v_speed_basic * v_sin;
            //_follow_v_speed += (follow_v_speed_target - _follow_v_speed) * Mathf.Min(1, Time.deltaTime * 5);
            //VRotate(_follow_v_speed);
        }
        else
        {
            _follow_h_speed += (0 - _follow_h_speed) * Mathf.Min(1, Time.deltaTime * 15);
            HRotate(_follow_h_speed);

            //_follow_v_speed += (0 - _follow_v_speed) * Mathf.Min(1, Time.deltaTime * 15);
            //VRotate(_follow_v_speed);
        }
    }

    // 和环境碰撞，修正像机位置
    void CollisonCheck()
    {
        // 使用SphereCast代替RayCast可以减少像机穿过地面和建筑的概率
        float cast_radius = 0.2f;
        float dis = (_camera_transform.position - _target_center).magnitude;
        int layer_mask = 1 | 1 << LayerMask.NameToLayer("Terrain");
        RaycastHit hit;
        if (Physics.SphereCast(_target_center, cast_radius, -_camera_transform.forward,
            out hit, dis, layer_mask))
        {
            _camera_transform.position = hit.point + hit.normal * cast_radius;
        }
        else
        {
            _camera_transform.position = _target_center - _camera_transform.forward * dis;
        }
    }

}
